import { signal, computed } from "@preact/signals";
import { moveItem, getIndex, turn } from "./utilities";
import { toast } from "./signals";
import { vendorEngines } from "./Vendor";

const key = "lemon_daisy_engines";
const stor = globalThis.localStorage;

const defaultEngines = [
  {
    name: "百度",
    url: "https://www.baidu.com/s?word=",
    theme: "secondary",
    checked: true,
  },
  {
    name: "Google",
    url: "https://www.google.com/search?query=",
    theme: "primary",
  },
  {
    name: "Bing",
    url: "https://cn.bing.com/search?q=",
    theme: "warning",
  },
  {
    name: "NPM",
    url: "https://www.npmjs.com/search?q=",
    theme: "accent",
  },
  {
    name: "GitHub",
    url: "https://github.com/search?q=",
    theme: "success",
  },
  {
    name: "MDN",
    url: "https://developer.mozilla.org/zh-CN/search?q=",
    theme: "info",
  },
  ...vendorEngines,
];

export const engines = signal(structuredClone(defaultEngines));

export const themes = {
  error: [
    "btn-error",
    "input-error",
    "caret-error",
    "text-error",
    "inset-ring-error",
  ],
  secondary: [
    "btn-secondary",
    "input-secondary",
    "caret-secondary",
    "text-secondary",
    "inset-ring-secondary",
  ],
  primary: [
    "btn-primary",
    "input-primary",
    "caret-primary",
    "text-primary",
    "inset-ring-primary",
  ],
  warning: [
    "btn-warning",
    "input-warning",
    "caret-warning",
    "text-warning",
    "inset-ring-warning",
  ],
  accent: [
    "btn-accent",
    "input-accent",
    "caret-accent",
    "text-accent",
    "inset-ring-accent",
  ],
  success: [
    "btn-success",
    "input-success",
    "caret-success",
    "text-success",
    "inset-ring-success",
  ],
  info: [
    "btn-info",
    "input-info",
    "caret-info",
    "text-info",
    "inset-ring-info",
  ],
};

export const themeNames = Object.values(themes);

export const checkedEngine = computed(() => {
  return engines.value.find((engine) => engine.checked);
});

export const checkedTheme = computed(() => {
  return themes[checkedEngine.value.theme];
});

export const engineKeywords = [
  "%s",
  "%S",
  "%@",
  "%keywords%",
  "%key%",
  "#KEY#",
  "{searchTerms}",
  "**",
];

export function initEngines() {
  if (stor[key]?.startsWith("[")) {
    const data = JSON.parse(stor[key]);
    engines.value = data;
  }
  stor[key] = JSON.stringify(engines.value);
}

function store(data) {
  stor[key] = JSON.stringify(data);
  engines.value = data;
}

export function checkEngine(name) {
  const current = structuredClone(engines.value);
  let count = 0;
  if (typeof name == "boolean") {
    const checked = getIndex(current, checkedEngine.value.name, "name");
    const destination = turn(checked, !name, 0, current.length - 1);
    name = destination;
  }
  for (const eng of current) {
    if (typeof name == "string") {
      eng.checked = eng.name === name;
    } else if (typeof name == "number") {
      eng.checked = count === name;
    }
    count++;
  }
  store(current);
}

export function editEngine(name, property, value) {
  const current = structuredClone(engines.value);
  const index = getIndex(current, name, "name");
  const existed = getIndex(current, value, "name") >= 0;
  if (property === "name" && (existed || value === name)) {
    toast("不支持重名引擎");
  } else {
    current[index][property] = value;
    store(current);
  }
}

export function delEngine(name) {
  const current = structuredClone(engines.value);
  if (current.length > 1) {
    const index = getIndex(current, name, "name");
    if (current[index].checked) {
      current[index === 0 ? 1 : 0].checked = true;
    }
    current.splice(index, 1);
    store(current);
  } else {
    toast("禁止删除");
  }
}

function genRandom() {
  return `引擎_${Number.parseInt(Math.random() * 2000, 10).toString(10)}`;
}

export function addEngine() {
  const current = structuredClone(engines.value);
  const newEngine = {
    name: genRandom(),
    url: "https://www.baidu.com/s?word=",
    theme: "error",
  };
  while (getIndex(current, newEngine.name, "name") >= 0) {
    newEngine.name = genRandom();
  }
  current.unshift(newEngine);
  store(current);
}

export function moveEngine(name, up) {
  const current = structuredClone(engines.value);
  const changed = moveItem(current, name, up, "name");
  store(changed);
}

export function exportEngines() {
  let text = "";
  for (const engine of JSON.parse(stor[key])) {
    text += `${engine.name}\n${engine.url}\n\n`;
  }
  return text;
}

export function clearEngines() {
  delete stor[key];
}

export function importEngines(data, merge) {
  let result = data;
  const current = structuredClone(engines.value);
  if (merge) {
    result = [
      ...current,
      ...data.filter((engine) => getIndex(current, engine.name, "name") === -1),
    ];
  }
  for (const eng of result) {
    eng.checked = false;
  }
  result[0].checked = true;
  store(result);
}

export function resetEngines() {
  importEngines(structuredClone(defaultEngines), false);
}
